using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Data;
using System.Net.Mail;

using GonzalesCore.CoreElements;
using GonzalesCore.CoreManagers;

using Kypris2.Utils;
using Kypris2.CoreElements;
using Kypris2.CoreManagers;

using Jamila2.CoreElements;
using Jamila2.Database;
using Jamila2.Tools;

namespace BPCSFileOutputDaemon
{
    public enum TypeOfFile { CSV, ColumnLengthOriented }

    public class FileGenerator 
    {
        protected PersonalSessionAccount CurrentSystemSession = null;
        string OutputDirectory = "", ArchieveDirectory = "";
        protected bool EmailActvie = false;
        protected string SMTP = "";
        public ArrayList LoggedMessages = new ArrayList();

        public FileGenerator(string output_path, string archieve_path, string DBConnectionString, TypeOfDatabase DatabaseType, bool Email_Active, string SMTP)
        {
            string NewFolderName = DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year + "-" + DateTime.Now.Hour + "-" + DateTime.Now.Minute;

            this.OutputDirectory = output_path;
            this.ArchieveDirectory = archieve_path + "\\" + NewFolderName + "\\";
            this.CurrentSystemSession = new PersonalSessionAccount(null, DatabaseType, DBConnectionString);
            this.EmailActvie = Email_Active;
            this.SMTP = SMTP;

            if (!Directory.Exists(this.ArchieveDirectory))
            {
                Directory.CreateDirectory(this.ArchieveDirectory);
            }

            Directory.CreateDirectory(this.OutputDirectory);
        }

        #region GenerateClaimTransactionFile

        public bool GenerateClaimTransactionFileX(TypeOfFile OutputType)
        {
            bool smooth = true;
            this.LoggedMessages = new ArrayList();

            StringBuilder ContentBuilder = new StringBuilder();
            StringBuilder LineItemBuilder = new StringBuilder();

            using (ClaimTransactionDataOutputManager CurManager = new ClaimTransactionDataOutputManager(this.CurrentSystemSession))
            {
                using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
                {
                    GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                    if (CompanyCollection != null)
                    {
                        LoggedMessages.Add("*** ECLAIMEXTRACT ***");

                        for (int z = 0; z < CompanyCollection.Count; z++)
                        {
                            ContentBuilder = new StringBuilder();
                            ArrayList ResultList = CurManager.GenerateFileContent(CompanyCollection[z].InternalID);

                            try
                            {
                                if (ResultList != null)
                                {
                                    string FileName = "ECLAIMEXTRACT-" + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + ".prn";
                                    string ActualPath = this.OutputDirectory + "\\" + FileName;

                                    // not null, can generate file
                                    for (int x = 0; x < ResultList.Count; x++)
                                    {
                                        string[] ResultData = (string[])ResultList[x];
                                        LineItemBuilder = new StringBuilder();

                                        for (int y = 0; y < CurManager.DataColumns.Count; y++)
                                        {
                                            switch (OutputType)
                                            {
                                                case TypeOfFile.CSV:
                                                    LineItemBuilder.Append(ResultData[CurManager.DataColumns[y].ColumnIndex] + ",");
                                                    break;

                                                case TypeOfFile.ColumnLengthOriented:
                                                    LineItemBuilder.Append(SwissArmy.StringAppend(ResultData[CurManager.DataColumns[y].ColumnIndex], " ", CurManager.DataColumns[y].Size, CurManager.DataColumns[y].FromBack));
                                                    break;
                                            }
                                        }

                                        ContentBuilder.AppendLine(LineItemBuilder.ToString());
                                    }

                                    // create file now
                                    SwissArmy.FileCreate(ActualPath, ContentBuilder.ToString());
                                    SwissArmy.FileCreate(this.ArchieveDirectory + FileName, ContentBuilder.ToString());
                                    LoggedMessages.Add("File Created: " + FileName);
                                }
                                else
                                {
                                    LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurManager.ErrorMessage);
                                }
                            }
                            catch (Exception ex)
                            {
                                LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                            }

                        }   // for z
                    }   // (CompanyCollection != null)
                }   // CompanyManagerr
            }   // ClaimTransactionDataOutputManager
                        
            return smooth;
        }

        public bool GenerateClaimTransactionFile(TypeOfFile OutputType)
        {
            bool smooth = true;
            this.LoggedMessages = new ArrayList();

            StringBuilder ContentBuilder = new StringBuilder();
            StringBuilder LineItemBuilder = new StringBuilder();

            using (ClaimTransactionDataOutputManager CurManager = new ClaimTransactionDataOutputManager(this.CurrentSystemSession))
            {
                using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
                {
                    GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                    if (CompanyCollection != null)
                    {
                        LoggedMessages.Add("*** ECLAIMEXTRACT ***");

                        for (int z = 0; z < CompanyCollection.Count; z++)
                        {
                            int[] PaymentDate = CurCompanyManager.GetPaymentDayByCompany(CompanyCollection[z].InternalID);
                            if (PaymentDate.Length <= 0) //added by thangnv 20130530
                            {
                                LoggedMessages.Add("The Company " + CompanyCollection[z].CompanyCode + " not yet define output date");
                                continue;
                            }

                            foreach (int CurDay in PaymentDate)
                            {
                                if (CurDay == DateTime.Now.Day)
                                {
                                    // found out is today!
                                    ContentBuilder = new StringBuilder();
                                    ArrayList ResultList = CurManager.GenerateFileContent(CompanyCollection[z].InternalID);

                                    try
                                    {
                                        if (ResultList != null)
                                        {
                                            string FileName = "ECLAIMEXTRACT-" + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + ".prn";
                                            string ActualPath = this.OutputDirectory + "\\" + FileName;

                                            // not null, can generate file
                                            for (int x = 0; x < ResultList.Count; x++)
                                            {
                                                string[] ResultData = (string[])ResultList[x];
                                                LineItemBuilder = new StringBuilder();

                                                for (int y = 0; y < CurManager.DataColumns.Count; y++)
                                                {
                                                    switch (OutputType)
                                                    {
                                                        case TypeOfFile.CSV:
                                                            LineItemBuilder.Append(ResultData[CurManager.DataColumns[y].ColumnIndex] + ",");
                                                            break;

                                                        case TypeOfFile.ColumnLengthOriented:
                                                            if(y == 12)
                                                                LineItemBuilder.Append(SwissArmy.StringAppend(ResultData[CurManager.DataColumns[y].ColumnIndex], " ", ResultData[CurManager.DataColumns[y].ColumnIndex].Length, CurManager.DataColumns[y].FromBack));
                                                            else
                                                                LineItemBuilder.Append(SwissArmy.StringAppend(ResultData[CurManager.DataColumns[y].ColumnIndex], " ", CurManager.DataColumns[y].Size, CurManager.DataColumns[y].FromBack));
                                                            break;
                                                    }
                                                }

                                                ContentBuilder.AppendLine(LineItemBuilder.ToString());
                                            }

                                            // create file now
                                            SwissArmy.FileCreate(ActualPath, ContentBuilder.ToString());
                                            SwissArmy.FileCreate(this.ArchieveDirectory + FileName, ContentBuilder.ToString());
                                            LoggedMessages.Add("File Created: " + FileName);

                                            #region Generate CSV too

                                            ContentBuilder = new StringBuilder();
                                            FileName = "ECLAIMEXTRACT-" + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + ".csv";
                                            ActualPath = this.OutputDirectory + "\\" + FileName;

                                            for (int x = 0; x < ResultList.Count; x++)
                                            {
                                                string[] ResultData = (string[])ResultList[x];
                                                LineItemBuilder = new StringBuilder();

                                                for (int y = 0; y < CurManager.DataColumns.Count; y++)
                                                {
                                                    LineItemBuilder.Append(ResultData[CurManager.DataColumns[y].ColumnIndex] + ",");
                                                }

                                                ContentBuilder.AppendLine(LineItemBuilder.ToString());
                                            }

                                            // create file now
                                            SwissArmy.FileCreate(ActualPath, ContentBuilder.ToString());
                                            SwissArmy.FileCreate(this.ArchieveDirectory + FileName, ContentBuilder.ToString());
                                            LoggedMessages.Add("File Created: " + FileName);

                                            #endregion
                                        }
                                        else
                                        {
                                            LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurManager.ErrorMessage);
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                                    }
                                }
                            }                            
                        }   // for z
                    }   // (CompanyCollection != null)
                }   // CompanyManagerr
            }   // ClaimTransactionDataOutputManager

            return smooth;
        }

        #endregion

        #region GenerateCreditCardTransactionFile

        public bool GenerateCreditCardTransactionFile(TypeOfFile OutputType)
        {
            bool smooth = true;
            this.LoggedMessages = new ArrayList();

            StringBuilder ContentBuilder = new StringBuilder();
            StringBuilder LineItemBuilder = new StringBuilder();

            using (CreditCardTransactionDataOutputManager CurManager = new CreditCardTransactionDataOutputManager(this.CurrentSystemSession))
            {
                using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
                {
                    GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                    if (CompanyCollection != null)
                    {
                        LoggedMessages.Add("*** CREDITCARD ***");

                        for (int z = 0; z < CompanyCollection.Count; z++)
                        {
                            if (CompanyCollection[z].CreditCardActivatedDay == DateTime.Now.Day)
                            {
                                ContentBuilder = new StringBuilder();
                                ArrayList ResultList = CurManager.GenerateFileContent(CompanyCollection[z].InternalID);

                                try
                                {
                                    if (ResultList != null)
                                    {
                                        string FileName = "CREDITCARD-" + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + ".prn";
                                        string ActualPath = this.OutputDirectory + "\\" + FileName;

                                        for (int x = 0; x < ResultList.Count; x++)
                                        {
                                            string[] ResultData = (string[])ResultList[x];
                                            LineItemBuilder = new StringBuilder();

                                            for (int y = 0; y < CurManager.DataColumns.Count; y++)
                                            {
                                                switch (OutputType)
                                                {
                                                    case TypeOfFile.CSV:
                                                        LineItemBuilder.Append(ResultData[CurManager.DataColumns[y].ColumnIndex] + ",");
                                                        break;

                                                    case TypeOfFile.ColumnLengthOriented:
                                                        LineItemBuilder.Append(SwissArmy.StringAppend(ResultData[CurManager.DataColumns[y].ColumnIndex], " ", CurManager.DataColumns[y].Size, CurManager.DataColumns[y].FromBack));
                                                        break;
                                                }
                                            }

                                            ContentBuilder.AppendLine(LineItemBuilder.ToString());
                                        }


                                        SwissArmy.FileCreate(ActualPath, ContentBuilder.ToString());
                                        SwissArmy.FileCreate(this.ArchieveDirectory + FileName, ContentBuilder.ToString());
                                        LoggedMessages.Add("File Created: " + FileName);
                                    }
                                    else
                                    {
                                        LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurManager.ErrorMessage);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                                }
                            }

                        }   // for z
                    }   // (CompanyCollection != null)
                }                
            }
            
            return smooth;
        }

        #endregion

        #region GenerateCreditCardReminder

        public bool GenerateCreditCardReminder()
        {
            bool smooth = true;
            this.LoggedMessages = new ArrayList();

            StringBuilder ContentBuilder = new StringBuilder();
            StringBuilder LineItemBuilder = new StringBuilder();

            using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
            {
                GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                if (CompanyCollection != null)
                {
                    LoggedMessages.Add("*** ECLAIMCREDITCARDREMINDER ***");

                    for (int z = 0; z < CompanyCollection.Count; z++)
                    {
                        int CreditCardReminder = Convert.ToInt32(CompanyCollection[z].CreditCardReminder);

                        if (CreditCardReminder > 0)
                        {
                            GonzalesCompany curCompany = new GonzalesCompany(CompanyCollection[z].InternalID, CompanyCollection[z].CompanyName);
                            CreditCardManager CurCreditCardManager = new CreditCardManager(this.CurrentSystemSession);
                            DataTable CreditCardCollection = CurCreditCardManager.GetAvailableCreditCardItemByCompany(CompanyCollection[z].InternalID, false);

                            try
                            {
                                if (CreditCardCollection.Rows.Count > 0)
                                {
                                    LoggedMessages.Add("Extract the Credit Card Item based on Company");

                                    string FileName = "ECLAIMCREDITCARDREMINDER-" + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + ".prn";
                                    string ActualPath = this.OutputDirectory + "\\" + FileName;

                                    for (int x = 0; x < CreditCardCollection.Rows.Count; x++)
                                    {
                                        LineItemBuilder = new StringBuilder();
                                        //LineItemBuilder.AppendLine(CreditCardCollection.Rows[x]["user_company"].ToString() + CreditCardCollection.Rows[x]["user_displayname"].ToString());
                                        DateTime Transaction_Date = Convert.ToDateTime(CreditCardCollection.Rows[x]["trans_Date"]).AddDays(CreditCardReminder);

                                        if (Transaction_Date.CompareTo(DateTime.Now) == 0)
                                        {
                                            #region Generate Email to approver and user.

                                            string mailContent = "";
                                            string title = "Reminder : " + CreditCardCollection.Rows[x]["trans_desc"].ToString() + " to be claimed.";

                                            mailContent += "Above credit card statement has been uploaded since " + CompanyCollection[z].ClaimReminder.ToString() + " days ago.";

                                            //send email to Credit Card Holder.
                                            SendEmail(mailContent, title, CreditCardCollection.Rows[x]["user_email"].ToString());

                                            LineItemBuilder.AppendLine(CreditCardCollection.Rows[x]["trans_desc"].ToString() + CreditCardCollection.Rows[x]["user_email"].ToString());

                                            #endregion
                                        }

                                        ContentBuilder.AppendLine(LineItemBuilder.ToString());
                                    }

                                    SwissArmy.FileCreate(ActualPath, ContentBuilder.ToString());
                                    SwissArmy.FileCreate(this.ArchieveDirectory + FileName, ContentBuilder.ToString());
                                    LoggedMessages.Add("File Created: " + FileName);
                                }
                                else
                                {
                                    LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurCreditCardManager.ErrorMessage);
                                }
                            }
                            catch (Exception ex)
                            {
                                LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                            }
                        }
                    }
                }
            }

            return smooth;
        }

        #endregion

        #region GenerateClaimReminder

        public bool GenerateClaimReminder()
        {
            bool smooth = true;
            this.LoggedMessages = new ArrayList();

            StringBuilder ContentBuilder = new StringBuilder();
            StringBuilder LineItemBuilder = new StringBuilder();

            using (CompanyManager CurCompanyManager = new CompanyManager(this.CurrentSystemSession))
            {
                GonzalesCompanies CompanyCollection = CurCompanyManager.GetAllCompany();

                if (CompanyCollection != null)
                {
                    LoggedMessages.Add("*** ECLAIMCLAIMREMINDER ***");

                    for (int z = 0; z < CompanyCollection.Count; z++)
                    {
                        int ClaimReminder = Convert.ToInt32(CompanyCollection[z].ClaimReminder);

                        GonzalesCompany curCompany = new GonzalesCompany(CompanyCollection[z].InternalID, CompanyCollection[z].CompanyName);
                        ClaimManager CurClaimManager = new ClaimManager(this.CurrentSystemSession);
                        ClaimHeaders ClaimCollection = CurClaimManager.GetClaimByStatus(GonzalesClaimHeader.TypeOfClaimStatus.Submitted, curCompany);

                        if (ClaimReminder > 0)
                        {
                            try
                            {

                                if (ClaimCollection != null)
                                {
                                    LoggedMessages.Add("Extract the Claim based on Company");
                                    string FileName = "ECLAIMCLAIMREMINDER-" + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + ".prn";
                                    string ActualPath = this.OutputDirectory + "\\" + FileName;

                                    for (int x = 0; x < ClaimCollection.Count; x++)
                                    {
                                        LineItemBuilder = new StringBuilder();
                                        //LineItemBuilder.AppendLine(ClaimCollection[x].CompanyClaimedFrom.CompanyName + ClaimCollection[x].ClaimID.ToString());

                                        if (ClaimCollection[x].SubmittedOn.AddDays(ClaimReminder).CompareTo(DateTime.Now) == 0)
                                        {
                                            #region Generate Email to approver and user.

                                            string mailContent = "";
                                            string title = "Reminder : " + ClaimCollection[x].ClaimID.ToString() + " to be Approved.";

                                            mailContent += "Above Claim has been Submitted for approval since " + CompanyCollection[z].ClaimReminder.ToString() + " days ago.";

                                            //send email to claimant.
                                            SendEmail(mailContent, title, ClaimCollection[x].ClaimedBy.Email);

                                            //send email to approver.
                                            SendEmail(mailContent, title, ClaimCollection[x].NextApprover.Email);

                                            LineItemBuilder.AppendLine(ClaimCollection[x].ClaimID.ToString() + ClaimCollection[x].NextApprover.Email);

                                            #endregion
                                        }

                                        ContentBuilder.AppendLine(LineItemBuilder.ToString());
                                    }

                                    SwissArmy.FileCreate(ActualPath, ContentBuilder.ToString());
                                    SwissArmy.FileCreate(this.ArchieveDirectory + FileName, ContentBuilder.ToString());
                                    LoggedMessages.Add("File Created: " + FileName);
                                }
                                else
                                {
                                    LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : " + CurClaimManager.ErrorMessage);
                                }
                            }
                            catch (Exception ex)
                            {
                                LoggedMessages.Add("File Failed for " + CompanyCollection[z].Entity.InternalID + CompanyCollection[z].CompanyCode + " : Exception : " + ex.Message);
                            }
                        }
                    }
                }
            }

            return smooth;
        }

        #endregion

        #region Generate Email
        public void SendEmail(string MailContent, string title, string EmailToAddress)
        {
            try
            {
                string EmailToAdd = EmailToAddress;
                string EmailFromAdd = "admin@covidien.com";
                string EmailFromName = "eClaim Admin";

                MailMessage mailMessage = new MailMessage();
                mailMessage.To.Add(new MailAddress(EmailToAdd));
                mailMessage.From = new MailAddress(EmailFromAdd, EmailFromName);
                mailMessage.Subject = title;
                mailMessage.Priority = MailPriority.High;
                mailMessage.BodyEncoding = Encoding.UTF8;
                mailMessage.IsBodyHtml = true;
                mailMessage.Body = MailContent;
                SmtpClient smtp = new SmtpClient(this.SMTP);
                smtp.Send(mailMessage);

            }
            catch (Exception ex)
            {
                LoggedMessages.Add("[SendEmail (" + title + ")] : Exception : " + ex.Message);
                LoggedMessages.Add("[SendEmail (" + title + ")] : Exception : " + ex.ToString());

            }

        }
        #endregion

    }
}
